/***************************************** 
 * Desc: 画布基类
 * @Author: GSan
 * @Email: 2087653648@qq.com
 * CreateDate: 2020-07-09 11:21:23
*****************************************/

using Common.UGUI.Base;
using UnityEngine;
using UnityEngine.UI;

namespace Common.UGUI.View {

    /// <summary>
    /// Canvas的层级
    /// </summary>
    public enum CanvasLayerType {

        Background = 0,

        Normal = 1000,

        Upper = 2000,

        Top = 3000,
    }

    [RequireComponent(typeof(Canvas))]
    [RequireComponent(typeof(CanvasScaler))]
    [RequireComponent(typeof(CanvasGroup))]
    [RequireComponent(typeof(GraphicRaycaster))]
    /// <summary>
    /// 此类作用主要是处理数据和提供一些规范的接口
    /// </summary>
	public class UGUICanvas : UGUIView{

        #region 域

        public CanvasLayerType CanvasLayerType { get { return _canvasLayerType; } set { _canvasLayerType = value; } }

        public Canvas Canvas {
            get {
                if(_canvas == null) {

                    _canvas = GameObject.GetComponent<Canvas>();
                }
                return _canvas;
            }
        }

        public CanvasScaler CanvasScaler {
            get {
                if(_canvasScaler == null) {

                    _canvasScaler = GameObject.GetComponent<CanvasScaler>();
                }
                return _canvasScaler;
            }
        }

        public GraphicRaycaster GraphicRaycaster {
            get {
                if(_graphicRaycaster == null) {

                    _graphicRaycaster = GameObject.GetComponent<GraphicRaycaster>();
                }
                return _graphicRaycaster;
            }
        }

        public CanvasGroup CanvasGroup {
            get {
                if (_canvasGroup == null) {

                    _canvasGroup = GameObject.GetComponent<CanvasGroup>();
                }
                return _canvasGroup;
            }
        }

        [SerializeField]
        private CanvasLayerType _canvasLayerType = CanvasLayerType.Background;
        private Canvas _canvas = null;
        private CanvasScaler _canvasScaler = null;
        private GraphicRaycaster _graphicRaycaster = null;
        private CanvasGroup _canvasGroup = null;

        #endregion

        #region 对象初始化

        protected override void OnAwake() {

            _canvas = GameObject.GetComponent<Canvas>();
            _canvas.renderMode = RenderMode.ScreenSpaceOverlay;

            _canvasScaler = GameObject.GetComponent<CanvasScaler>();
            _graphicRaycaster = GameObject.GetComponent<GraphicRaycaster>();
            _canvasGroup = GameObject.GetComponent<CanvasGroup>();

            _canvas.sortingOrder = (int)CanvasLayerType + SortingOrder;
        }

        protected override void OnDestroyByMono() {

            _canvas = null;
            _canvasScaler = null;
            _graphicRaycaster = null;
        }

        #endregion

        #region 接口

        /// <summary>
        /// 由当前的CanvasLayerType 和 SortingOrder 共同决定现在的SortingOrder
        /// </summary>
        public override void SortGameObjectBySortingOrder() {
            Canvas.sortingOrder = (int)CanvasLayerType + SortingOrder;
        }

        /// <summary>
        /// 设置分辨率
        /// </summary>
        public void SetResolution(int x, int y) {
            CanvasScaler.referenceResolution = new Vector2(x,y);
        }

        #endregion

        #region 覆盖父类函数

#if UNITY_EDITOR

        public void SetEditorActive(bool isActive) {
            _isActive = isActive;

            if (isActive) {

                if (OnEnable != null) {

                    OnEnable();
                }

                CanvasGroup.alpha = 1;
                CanvasGroup.interactable = _isActive;
                CanvasGroup.blocksRaycasts = _isActive;
                GameObject.SetActive(true);
            } else {

                if (OnDisable != null) {

                    OnDisable();
                }

                CanvasGroup.alpha = 0;
                CanvasGroup.interactable = _isActive;
                CanvasGroup.blocksRaycasts = _isActive;
                GameObject.SetActive(true);
            }
        }
#endif

        public override void SetActive(bool isActive) {

            _isActive = isActive;

            if (isActive) {

                if (OnEnable != null) {

                    OnEnable();
                }

                CanvasGroup.alpha = 1;
                CanvasGroup.interactable = _isActive;
                CanvasGroup.blocksRaycasts = _isActive;
            } else {

                if (OnDisable != null) {

                    OnDisable();
                }

                CanvasGroup.alpha = 0;
                CanvasGroup.interactable = _isActive;
                CanvasGroup.blocksRaycasts = _isActive;
            }
        }

        protected override bool AddChild(UGUIView uguiView) {

            if (uguiView is UGUIPanel) {

                base.AddChild(uguiView);

                return true;
            } else {

                Debug.LogError("UGUICanvas add child must be a UGUIPanel, view: " + uguiView.Name + " is not a UGUIPanel.");

                uguiView.SetParent(null);

                return false;
            }
        }

#endregion
    }
}
